﻿
using LogHelper;
using Microsoft.AspNetCore.SignalR;
using Newtonsoft.Json;
using PLCS.Client.Service.EquipmentManager;
using PLCS.Domain.Logs;
using PLCS.Domain.Shared.Equipments;
using PLCS.Domain.Stations;
using PLCS.Domain.Trays;
using PLCS.EquipmentService.BackgroundWorks.rgvs;
using PLCS.EquipmentService.Models;
using PLCS.EquipmentService.ParsersHelpers;
using PLCS.PlcInteraction.PLCHelper;
using PLCS.Shared.Common.Constant;
using PLCS.SocialHttpClient;
using PLCS.SocialHttpClient.WMS;
using PLCS.SocialHttpClient.WMS.Models;

using System.Diagnostics;
using System.Security.Cryptography;
using System.Threading.Tasks;
using Volo.Abp.Uow;

namespace PLCS.EquipmentService.BackgroundWorks.Analysis;

[DisallowConcurrentExecution]

public class TaskAnalysisWorker : QuartzBackgroundWorkerBase
{
    private readonly ITaskRepository _taskRepository;
    private readonly IInstructionRepository _instructionRepository;
    private readonly PathAnalyzer _dataAnalyzer;
    private readonly IStationRepository _stationRepository;
    private readonly ITrayRepository _trayRepository;
    private readonly ILogger<TaskAnalysisWorker> _logger;
    private readonly ApiRequestService apiRequestService;
    private readonly WMSSocialService wMSSocialService;
    private readonly TaskParser _taskParser;
    private readonly IEquipmentRepository _equipmentRepository;

    public TaskAnalysisWorker(ITaskRepository taskRepository,
                              IInstructionRepository instructionRepository,
                              PathAnalyzer dataAnalyzer,
                              IStationRepository stationRepository,
                              ILogger<TaskAnalysisWorker> logger,
                              ApiRequestService apiRequestService,
                              WMSSocialService wMSSocialService,
                              ITrayRepository trayRepository,
                              TaskParser taskParser,
                              IEquipmentRepository equipmentRepository)
    {
        JobDetail = JobBuilder.Create<TaskAnalysisWorker>().WithIdentity(nameof(TaskAnalysisWorker)).Build();
        Trigger = TriggerBuilder.Create().WithIdentity(nameof(TaskAnalysisWorker))
            .WithSimpleSchedule(s => s.WithIntervalInSeconds(1)
            .RepeatForever()
            .WithMisfireHandlingInstructionIgnoreMisfires())
            .Build();

        ScheduleJob = async scheduler =>
        {
            if (!await scheduler.CheckExists(JobDetail.Key))
            {
                await scheduler.ScheduleJob(JobDetail, Trigger);
            }
        };
        _taskRepository = taskRepository;
        _instructionRepository = instructionRepository;
        _dataAnalyzer = dataAnalyzer;
        _stationRepository = stationRepository;
        _logger = logger;
        this.apiRequestService = apiRequestService;
        this.wMSSocialService = wMSSocialService;
        _trayRepository = trayRepository;
        _taskParser = taskParser;
        _equipmentRepository = equipmentRepository;
    }
    int i = 0;
    [UnitOfWork]//解决方案肯定是在GetAll执行前打开数据库链接咯。既然UnitOfWork负责链接和事务，那么就在方法上添加[UnitOfWork]特性就可以了。
    public override async Task Execute(IJobExecutionContext context)
    {
        try
        {
          
            TaskDone().Wait();
            await LiveVersion();
        }
        catch (Exception ex)
        {
        }
        await ViewsUpdate();
    }
    /// <summary>
    /// 实际调度逻辑
    /// </summary>
    /// <returns></returns>
    public async Task LiveVersion()
    {
        List<string> Uppernames = new List<string>();//上侧工位号
        List<string> Lowernames = new List<string>();//下侧工位号
        for (int i = 1; i <= 16; i++)
        {
            if (i <= 9) Uppernames.Add($"ST000{i}");
            else Uppernames.Add($"ST00{i}");
        }
        for (int i = 18; i <= 33; i++)
        {
            Lowernames.Add($"ST00{i}");
        }
        List<TaskModel> ST0034task = new List<TaskModel>();//上侧堆垛机任务
        List<TaskModel> ST0035task = new List<TaskModel>();//下侧堆垛机任务
        List<TaskModel> OtherTasks = new List<TaskModel>();//库内转移任务
        var tasklist = await _taskRepository.GetListAsync(x => x.TaskStatus == Domain.Shared.Tasks.TaskStatus.未执行);
        ///任务分类
        foreach (var task in tasklist)
        {
            bool select = true;
            if (Uppernames.Contains(task.StartPos) || Uppernames.Contains(task.EndPos))
            {
                select = false;
                ST0034task.Add(task);
            }
            if (Lowernames.Contains(task.EndPos) || Lowernames.Contains(task.StartPos))
            {
                select = false;
                ST0035task.Add(task);
            }
            if(!select) OtherTasks.Add(task);

        }

        foreach (var task in ST0034task)
        {
            var st34 = await _equipmentRepository.FirstOrDefaultAsync(x => x.EquName == "ST0034");
            var start = await _stationRepository.FirstOrDefaultAsync(x => x.StaName == task.StartPos);
            var end = await _stationRepository.FirstOrDefaultAsync(x => x.StaName == task.EndPos);
            if (st34.Status == DeviceStatus.空闲 && start.HaveStatus == YesNo.是 && end.HaveStatus == YesNo.否)
            {
                new Log().AddLog("ST0034堆垛机执行任务  " + task.StartPos + "  " + task.EndPos);
                SendToPLCAsync(st34,task).Wait();
                
            }
        }
        foreach (var task in ST0035task)
        {
            var st35 = await _equipmentRepository.FirstOrDefaultAsync(x => x.EquName == "ST0035");
            var start = await _stationRepository.FirstOrDefaultAsync(x => x.StaName == task.StartPos);
            var end = await _stationRepository.FirstOrDefaultAsync(x => x.StaName == task.EndPos);
            if (st35.Status == DeviceStatus.空闲 && start.HaveStatus == YesNo.是 && end.HaveStatus == YesNo.否)
            {
                new Log().AddLog("ST0035堆垛机执行任务  " + task.StartPos + "  " + task.EndPos);
                SendToPLCAsync(st35, task).Wait();
            }
        }
        //移库任务
        foreach (var task in OtherTasks)
        {
            var st34 = await _equipmentRepository.FirstOrDefaultAsync(x => x.EquName == "ST0034");
            var st35 = await _equipmentRepository.FirstOrDefaultAsync(x => x.EquName == "ST0035");
            if (st34.Status == DeviceStatus.空闲 && st35.Status == DeviceStatus.空闲)
            {
                if (Math.Abs(int.Parse(st35.CurrentColume) - int.Parse(task.StartPos.Split("-")[2])) <= Math.Abs(int.Parse(st34.CurrentColume) - int.Parse(task.StartPos.Split("-")[2])))
                {
                    new Log().AddLog("ST0035堆垛机执行任务  " + task.StartPos + "  " + task.EndPos);
                    SendToPLCAsync(st35, task).Wait();
                }
                else
                {
                    new Log().AddLog("ST0034堆垛机执行任务  " + task.StartPos + "  " + task.EndPos);
                    SendToPLCAsync(st34, task).Wait();
                }
            }
            if (st34.Status == DeviceStatus.忙碌 && st35.Status == DeviceStatus.空闲)
            {
                new Log().AddLog("ST0035堆垛机执行任务  " + task.StartPos + "  " + task.EndPos);
                SendToPLCAsync(st35, task).Wait();
            }
            if (st35.Status == DeviceStatus.忙碌 && st34.Status == DeviceStatus.空闲)
            {
                new Log().AddLog("ST0034堆垛机执行任务  " + task.StartPos + "  " + task.EndPos);
                SendToPLCAsync(st34, task).Wait();
            }

        }
    }
    /// <summary>
    /// plc指令下发
    /// </summary>
    /// <param name="eq">设备实体</param>
    /// <param name="task">任务</param>
    /// <returns></returns>
    public async Task SendToPLCAsync(Equipment eq, TaskModel task)
    {
        if (eq.OnlineStatus != OnlineMode.联机) return;
        var start = await _stationRepository.FirstOrDefaultAsync(x => x.StaName == task.StartPos);
        var end = await _stationRepository.FirstOrDefaultAsync(x => x.StaName == task.EndPos);
        ///被别的任务占用跳出
        if (start.IsBeUsed || end.IsBeUsed)
        {
            return;
        }
        List<string> Uppernames = new List<string>();//上侧工位号
        List<string> Lowernames = new List<string>();//下侧工位号
        for (int i = 1; i <= 16; i++)
        {
            if (i <= 9) Uppernames.Add($"ST000{i}");
            else Uppernames.Add($"ST00{i}");
        }
        for (int i = 18; i <= 33; i++)
        {
            Lowernames.Add($"ST00{i}");
        }
        ///可取送逻辑
        if (Uppernames.Contains(task.StartPos) || Lowernames.Contains(task.EndPos) )
        {
            if (start.CanGet || start.HaveStatus== YesNo.否) return;
        }
        if (Uppernames.Contains(task.EndPos) || Lowernames.Contains(task.EndPos))
        {
            if (end.CanSend ||  end.HaveStatus== YesNo.是) return;
        }
        
        S7Client client = new S7Client();
        byte[] buffer = new byte[100];
        S7.SetDIntAt(buffer, 0, task.TaskId);
        S7.SetDIntAt(buffer, 4, 4);//取放货
        S7.SetDIntAt(buffer, 28, int.Parse( start.StaName_Lower.Split("-")[0]));
        S7.SetDIntAt(buffer, 32, int.Parse(start.StaName_Lower.Split("-")[1]));
        S7.SetDIntAt(buffer, 36, int.Parse(start.StaName_Lower.Split("-")[2]));
        S7.SetDIntAt(buffer, 40, int.Parse(start.StaName_Lower.Split("-")[3]));
        S7.SetDIntAt(buffer, 44, int.Parse(end.StaName_Lower.Split("-")[0]));
        S7.SetDIntAt(buffer, 48, int.Parse(end.StaName_Lower.Split("-")[1]));
        S7.SetDIntAt(buffer, 52, int.Parse(end.StaName_Lower.Split("-")[2]));
        S7.SetDIntAt(buffer, 56, int.Parse(end.StaName_Lower.Split("-")[3]));
        S7.SetDIntAt(buffer, 96, 1);//开始信号
        if (eq.EquName == "ST0034" )
        {
            if (client.ConnectTo("192.168.0.10", 0, 1) == 0)
            {
                if (client.DBWrite(600, 0, 100, buffer) == 0)
                {
                    task.TaskStatus = Domain.Shared.Tasks.TaskStatus.执行中;
                    await _taskRepository.UpdateAsync(task);
                    
                    start.HaveStatus = YesNo.否;
                    end.HaveStatus = YesNo.是;
                    start.IsBeUsed = true;
                    end.IsBeUsed= true;
                    await _stationRepository.UpdateAsync(start);
                    await _stationRepository.UpdateAsync(end);
                }

            }
            else
            {
               new Log().AddLog("plc连接失败");
            }
        }
        if (eq.EquName == "ST0035")
        {
            if (client.ConnectTo("192.168.0.10", 0, 1) == 0)
            {
                if (client.DBWrite(600, 100, 100, buffer) == 0)
                {

                    task.TaskStatus = Domain.Shared.Tasks.TaskStatus.执行中;
                    await _taskRepository.UpdateAsync(task);
                   
                    start.HaveStatus = YesNo.否;
                    end.HaveStatus = YesNo.是;
                    start.IsBeUsed = true;
                    end.IsBeUsed = true;
                    await _stationRepository.UpdateAsync(start);
                    await _stationRepository.UpdateAsync(end);
                }

            }
            else
            {
                new Log().AddLog("plc连接失败");
            }
        }
    }
    /// <summary>
    /// 任务完工
    /// </summary>
    /// <returns></returns>
    public async Task TaskDone()
    {
        var tasklis = await _taskRepository.GetListAsync(x=>x.TaskStatus== Domain.Shared.Tasks.TaskStatus.执行中);
        foreach (var task in tasklis) 
        {
            var start = await _stationRepository.FirstOrDefaultAsync(x => x.StaName == task.StartPos);
            var end = await _stationRepository.FirstOrDefaultAsync(x => x.StaName == task.EndPos);
            var curreq = await _equipmentRepository.FirstOrDefaultAsync(x=>x.CurrentTaskId== task.TaskId);
            if (curreq?.CompleteSignal == "1")
            {
                task.TaskStatus = Domain.Shared.Tasks.TaskStatus.已完成;
                await _taskRepository.UpdateAsync(task);
                start.IsBeUsed = false;
                end.IsBeUsed= false;
                await _stationRepository.UpdateAsync(start);
                await _stationRepository.UpdateAsync(end);
                ///给wms反馈完工信号
                {
                    await wMSSocialService.ReportTaskAsync(task.TaskId_Higher.ToString(),2);
                }
            }
        }
    }
    /// <summary>
    /// 更新界面
    /// </summary>
    /// <returns></returns>
    public async Task ViewsUpdate()
    {
        var RGV1 = await _equipmentRepository.FirstOrDefaultAsync(x=>x.EquName=="ST0034");
        var RGV2 = await _equipmentRepository.FirstOrDefaultAsync(x => x.EquName == "ST0035");
        RGV1.ChangeRGVStatus(RGV1.Status);
        RGV2.ChangeRGVStatus(RGV2.Status);
    }
    /// <summary>
    /// 原始代码
    /// </summary>
    /// <returns></returns>
    public async Task Origionversion()
    {
        #region
        //try
        //{
        //    // 获取所有未完成的任务
        //    var tasks = await _taskRepository.GetUnfinshedTaskAsync();
        //    // 如果没有则跳出
        //    if (!tasks.Any())
        //        return;

        //    var stations = await _stationRepository.GetListAsync(true);

        //    // 先创建一个等待新增的指令集合，晚点遍历完所有的任务一起添加
        //    var waitAddInstructions = new List<Instruction>();
        //    foreach (var task in tasks)
        //    {
        //        var startStation = stations.FirstOrDefault(x => x.StaNum == task.StartPos);
        //        var endStation = stations.FirstOrDefault(x => x.StaNum == task.EndPos);

        //        if (task.StartPos == task.EndPos)
        //        {
        //            var errorMessage = $"起始位和目标位不能相同";
        //            await HandleErrorAndContinueAsync(task, errorMessage);
        //            continue;
        //        }

        //        var instructions = new List<Instruction>();
        //        switch (task.TaskType)
        //        {
        //            case Domain.Shared.Tasks.TaskType.普通流转:
        //                if (startStation == null || endStation == null)
        //                {
        //                    var errorMessage = $"起始位和目标位不能为空";
        //                    await HandleErrorAndContinueAsync(task, errorMessage);
        //                    continue;
        //                }

        //                // 检查工位是否能进
        //                if (!await _taskParser.CheckStation(endStation, tasks))
        //                {
        //                    string bestFitWorkstation = await _taskParser.GetBestFitWorkstation(stations, endStation, tasks, task);
        //                    if (bestFitWorkstation != endStation.StaNum)
        //                    {
        //                        task.EndPos = bestFitWorkstation;
        //                        await _taskRepository.UpdateAsync(task);
        //                    }
        //                }

        //                // 先判断目标位是否有缓存工位，如果没有的话，就不查询任务，减少内存消耗。
        //                // 如果目标位满位或者有任务去的话，但是有缓存工位的话，先去缓存工位，等空了在过去。
        //                if (!string.IsNullOrEmpty(endStation.CacheStation))
        //                {
        //                    var endTasks = await _taskRepository.GetUnfinshedAboutRunningTaskAsync();
        //                    if (endStation.HaveStatus == YesNo.是 || endTasks.Where(x => x.EndPos == endStation.StaNum).Any())
        //                    {
        //                        var cacheEndStation = stations.FirstOrDefault(x => x.StaNum == endStation.CacheStation);
        //                        if (cacheEndStation != null)
        //                        {
        //                            var instructions1 = await _dataAnalyzer.SplitOptimalPathTasksAsync(startStation.StaNum, cacheEndStation.StaNum);
        //                            var instructions2 = await _dataAnalyzer.SplitOptimalPathTasksAsync(cacheEndStation.StaNum, endStation.StaNum);
        //                            instructions.AddRange(instructions1);
        //                            instructions.AddRange(instructions2);

        //                            instructions = TaskParser.ReorderTaskNumbers(instructions, task);
        //                            break;
        //                        }
        //                    }
        //                }

        //                instructions = await _dataAnalyzer.SplitOptimalPathTasksAsync(task);
        //                break;

        //            case Domain.Shared.Tasks.TaskType.出库:
        //                // 如果目标位为空，或者起始为为空并且托盘号也为空，那就不对了。
        //                if (endStation == null || (startStation == null && string.IsNullOrEmpty(task.TrayNo)))
        //                {
        //                    var errorMessage = $"起始位和托盘号不可都为空";
        //                    await HandleErrorAndContinueAsync(task, errorMessage);
        //                    continue;
        //                }
        //                if (startStation != null)
        //                {
        //                    var startTray = startStation?.Trays?.FirstOrDefault();
        //                    if (startTray != null)
        //                    {
        //                        task.TrayNo = startTray.TrayNo;
        //                        task.TrayType = startTray.TrayType;
        //                    }

        //                    await _taskRepository.UpdateAsync(task);
        //                }
        //                // 如果起始位为空，但是托盘号不为空，那么就从库里找一找这个托盘的位置。
        //                else if (startStation == null && !string.IsNullOrEmpty(task.TrayNo))
        //                {
        //                    var tray = await _trayRepository.GetTrayByNoAsync(task.TrayNo);
        //                    var staNum = tray?.Station?.StaNum;
        //                    startStation = stations.FirstOrDefault(x => x.StaNum == staNum);

        //                    // 如果没找到，那就是不对啦。
        //                    if (startStation == null)
        //                    {
        //                        var errorMessage = $"在库中没有找到托盘号{task.TrayNo}";
        //                        await HandleErrorAndContinueAsync(task, errorMessage);
        //                        continue;
        //                    }
        //                    // 找到了的话就把起始位和托盘类型重新赋值更新一下。
        //                    task.StartPos = staNum;
        //                    task.TrayType = tray.TrayType;
        //                    await _taskRepository.UpdateAsync(task);
        //                }

        //                instructions = await _dataAnalyzer.SplitOptimalPathTasksAsync(task);
        //                break;

        //            case Domain.Shared.Tasks.TaskType.出库_双排:

        //                // 如果目标位为空，或者起始为为空并且托盘号也为空，那就不对了。
        //                if (endStation == null || (startStation == null && string.IsNullOrEmpty(task.TrayNo)))
        //                {
        //                    var errorMessage = $"起始位和托盘号不可都为空";
        //                    await HandleErrorAndContinueAsync(task, errorMessage);
        //                    continue;
        //                }
        //                if (startStation != null)
        //                {
        //                    var startTray = startStation?.Trays?.FirstOrDefault();
        //                    if (startTray != null)
        //                    {
        //                        task.TrayNo = startTray.TrayNo;
        //                        task.TrayType = startTray.TrayType;
        //                    }

        //                    await _taskRepository.UpdateAsync(task);
        //                }
        //                // 如果起始位为空，并且托盘号不为空，那么就从库里找一找这个托盘的位置。
        //                else if (startStation == null && !string.IsNullOrEmpty(task.TrayNo))
        //                {
        //                    var tray = await _trayRepository.GetTrayByNoAsync(task.TrayNo);
        //                    var staNum = tray?.Station?.StaNum;
        //                    startStation = stations.FirstOrDefault(x => x.StaNum == staNum);

        //                    // 如果没找到，那就是不对啦。
        //                    if (startStation == null)
        //                    {
        //                        var errorMessage = $"在库中没有找到托盘号{task.TrayNo}";
        //                        await HandleErrorAndContinueAsync(task, errorMessage);
        //                        continue;
        //                    }
        //                    // 找到了的话就把起始位和托盘类型重新赋值更新一下。
        //                    task.StartPos = staNum;
        //                    task.TrayType = tray.TrayType;
        //                    await _taskRepository.UpdateAsync(task);
        //                }

        //                var staNumParts = startStation.StaNum.Split('-');
        //                if (staNumParts.Length >= 3)
        //                {
        //                    var column = int.Parse(staNumParts[1]);
        //                    if (column == 1 || column == 4)
        //                    {
        //                        var sanmeRowNum = $"{staNumParts[0]}-{(column == 1 ? 2 : 3)}-{staNumParts[2]}-{staNumParts[3]}";
        //                        var sanmeRow = stations.FirstOrDefault(x => x.StaNum == sanmeRowNum);
        //                        if (sanmeRow != null && sanmeRow.HaveStatus == YesNo.是)
        //                        {
        //                            // 需要移库
        //                            // 0.找到这个货位附近最近的一个空位(左右，对面左右)且是同规格的货位
        //                            // 1.添加一个把外面货位移库到其他货位的指令
        //                            // 2.照常执行任务流转逻辑，生成指令
        //                            // 3.再添加一个把原来货位搬回的指令（暂时不搬了）

        //                            var newStation = await _taskParser.FindNearestEmptyStation(sanmeRow, stations);
        //                            var instructions1 = await _dataAnalyzer.SplitOptimalPathTasksAsync(sanmeRowNum, newStation.StaNum);
        //                            var instructions2 = await _dataAnalyzer.SplitOptimalPathTasksAsync(task);
        //                            //var instructions3 = await _dataAnalyzer.SplitOptimalPathTasksAsync(newStation.StaNum, sanmeRowNum);
        //                            instructions.AddRange(instructions1);
        //                            instructions.AddRange(instructions2);
        //                            //instructions.AddRange(instructions3);
        //                            instructions = TaskParser.ReorderTaskNumbers(instructions, task);
        //                        }
        //                        else
        //                        {
        //                            instructions = await _dataAnalyzer.SplitOptimalPathTasksAsync(task);
        //                        }
        //                    }
        //                    else
        //                    {
        //                        instructions = await _dataAnalyzer.SplitOptimalPathTasksAsync(task);
        //                    }
        //                }
        //                else
        //                {
        //                    var errorMessage = $"起始位不是货位{startStation.StaNum}";
        //                    await HandleErrorAndContinueAsync(task, errorMessage);
        //                    continue;
        //                }
        //                break;

        //            case Domain.Shared.Tasks.TaskType.入库:
        //                // 起始位空，那就不对了
        //                if (startStation == null)
        //                {
        //                    var errorMessage = $"起始位不可为空";
        //                    await HandleErrorAndContinueAsync(task, errorMessage);
        //                    continue;
        //                }

        //                var materialSize = GlobalModel.maxMaterialSize - 1;

        //                // 如果起始位有托盘，获取其托盘类型
        //                if (startStation.Trays != null && startStation.Trays.Any())
        //                {
        //                    var tray = startStation.Trays.First();
        //                    task.TrayType = tray.TrayType;
        //                    materialSize = tray.MaterialSize == 0 ? materialSize : tray.MaterialSize;
        //                }
        //                else
        //                {
        //                    var errorMessage = $"起始位未查询到托盘";
        //                    await HandleErrorAndContinueAsync(task, errorMessage);
        //                    continue;
        //                }

        //                // 如果没有指定目标位，则自己找一个合适的。
        //                endStation ??= await _taskParser.FindAvailableStorageStation(task.TrayType, materialSize, stations);
        //                if (endStation == null)
        //                {
        //                    var errorMessage = $"没有找到合适的库位";
        //                    await HandleErrorAndContinueAsync(task, errorMessage);
        //                    continue;
        //                }
        //                task.EndPos = endStation.StaNum;
        //                await _taskRepository.UpdateAsync(task);
        //                instructions = await _dataAnalyzer.SplitOptimalPathTasksAsync(task);

        //                break;

        //            case Domain.Shared.Tasks.TaskType.移库:
        //                // 起始位空，那就不对了
        //                if (startStation == null || endStation == null)
        //                {
        //                    var errorMessage = $"起始位或目标位不能为空";
        //                    await HandleErrorAndContinueAsync(task, errorMessage);
        //                    continue;
        //                }

        //                instructions = await _dataAnalyzer.SplitOptimalPathTasksAsync(task);
        //                break;

        //            case Domain.Shared.Tasks.TaskType.移库_双排:
        //                // 起始位空，那就不对了
        //                if (startStation == null || endStation == null)
        //                {
        //                    var errorMessage = $"起始位或目标位不能为空";
        //                    await HandleErrorAndContinueAsync(task, errorMessage);
        //                    continue;
        //                }

        //                var startstaNumParts = startStation.StaNum.Split('-');
        //                if (startstaNumParts.Length >= 3)
        //                {
        //                    var column = int.Parse(startstaNumParts[1]);
        //                    if (column == 1 || column == 4)
        //                    {
        //                        var sanmeRowNum = $"{startstaNumParts[0]}-{(column == 1 ? 2 : 3)}-{startstaNumParts[2]}-{startstaNumParts[3]}";
        //                        var sanmeRow = stations.FirstOrDefault(x => x.StaNum == sanmeRowNum);
        //                        if (sanmeRow != null && sanmeRow.HaveStatus == YesNo.是)
        //                        {
        //                            // 需要移库
        //                            // 0.找到这个货位附近最近的一个空位(左右，对面左右)且是同规格的货位
        //                            // 1.添加一个把外面货位移库到其他货位的指令
        //                            // 2.照常执行任务流转逻辑，生成指令
        //                            // 3.再添加一个把原来货位搬回的指令（暂时不搬了）

        //                            var newStation = await _taskParser.FindNearestEmptyStation(sanmeRow, stations.Where(x => x.StaNum != endStation.StaNum).ToList());
        //                            var instructions1 = await _dataAnalyzer.SplitOptimalPathTasksAsync(sanmeRowNum, newStation.StaNum);
        //                            var instructions2 = await _dataAnalyzer.SplitOptimalPathTasksAsync(task);
        //                            //var instructions3 = await _dataAnalyzer.SplitOptimalPathTasksAsync(newStation.StaNum, sanmeRowNum);
        //                            instructions.AddRange(instructions1);
        //                            instructions.AddRange(instructions2);
        //                            //instructions.AddRange(instructions3);
        //                            instructions = TaskParser.ReorderTaskNumbers(instructions, task);
        //                        }
        //                        else
        //                        {
        //                            instructions = await _dataAnalyzer.SplitOptimalPathTasksAsync(task);
        //                        }
        //                    }
        //                    else
        //                    {
        //                        instructions = await _dataAnalyzer.SplitOptimalPathTasksAsync(task);
        //                    }
        //                }
        //                else
        //                {
        //                    var errorMessage = $"起始位不是货位{startStation.StaNum}";
        //                    await HandleErrorAndContinueAsync(task, errorMessage);
        //                    continue;
        //                }
        //                break;

        //            case Domain.Shared.Tasks.TaskType.多工位RGV任务:
        //                if (string.IsNullOrEmpty(task.StartPos) || string.IsNullOrEmpty(task.EndPos))
        //                {
        //                    var errorMessage = $"起始位和目标位不能为空";
        //                    await HandleErrorAndContinueAsync(task, errorMessage);
        //                    continue;
        //                }

        //                var startPositionNos = task.StartPos.Split(ConstantChar.SplitChar);
        //                var endPositionNos = task.EndPos.Split(ConstantChar.SplitChar);

        //                if (startPositionNos.Length != endPositionNos.Length)
        //                {
        //                    var errorMessage = $"多工位RGV任务下，起始位数量和目标位数量不一致";
        //                    await HandleErrorAndContinueAsync(task, errorMessage);
        //                    continue;
        //                }
        //                // 起始位工位集合
        //                var startPositions = await _stationRepository.GetListAsync(x => startPositionNos.Contains(x.StaNum));
        //                // 目的位工位集合
        //                var endPositions = await _stationRepository.GetListAsync(x => endPositionNos.Contains(x.StaNum));

        //                // 确定执行设备编号
        //                var equipmentNo = string.Join(ConstantChar.SplitChar, startPositions.First().CanTake_EquNum.Split(ConstantChar.SplitChar).Where(x => endPositions.First().CanSend_EquNum.Contains(x)));
        //                var equipment = await _equipmentRepository.GetByEquipmentNoAsync(equipmentNo);

        //                var paths = TaskParser.CalculateAllPaths(startPositions, endPositions, equipment.CurrentPos);
        //                var instruction7s = new List<Instruction>();
        //                var path = paths.First();

        //                foreach (var item in path)
        //                {
        //                    var instructionType = startPositionNos.Contains(item.StaNum) ? Domain.Shared.Tasks.InstructionType.单取货 : Domain.Shared.Tasks.InstructionType.单放货;
        //                    var instruction = new Instruction(0, null, equipmentNo, instructionType, instructionType == Domain.Shared.Tasks.InstructionType.单取货 ? item.StaNum : null, instructionType == Domain.Shared.Tasks.InstructionType.单放货 ? item.StaNum : null);
        //                    instruction7s.Add(instruction);
        //                }

        //                instructions = TaskParser.ReorderTaskNumbers(instruction7s, task);

        //                break;

        //            default:
        //                break;
        //        }

        //        if (!instructions.Any())
        //        {
        //            var errorMessage = $"没有解析出任何一条路径";
        //            await HandleErrorAndContinueAsync(task, errorMessage);
        //        }
        //        else
        //        {
        //            task.ChangeStatus(Domain.Shared.Tasks.TaskStatus.解析完成);
        //            task.SetRemark(string.Empty);
        //            waitAddInstructions.AddRange(instructions);
        //            await _taskRepository.UpdateAsync(task);
        //        }
        //        await Task.Delay(100);
        //    }

        //    await _instructionRepository.InsertManyAsync(waitAddInstructions);//插入指令
        //}
        //catch (Exception ex)
        //{
        //    _logger.LogException(ex);
        //}
        #endregion
    }
    private async Task HandleErrorAndContinueAsync(TaskModel task, string message)
    {
        _logger.LogWarning($"任务号:{task.TaskId}解析失败，失败原因：{message}");
        task.ChangeStatus(Domain.Shared.Tasks.TaskStatus.解析失败);
        task.SetRemark(message);
        await _taskRepository.UpdateAsync(task);
    }
}